/*
 * RTSAI - Real-Time Strategy engine for AI research
 * Copyright(C) 2006 DIMAp-UFRN, licensed under LGPL
 *
 * RTSAI Testing application
 */

#include <sstream>

#include "rtsai.h"
#include "Common.h"
#include "GameView.h"
#include "UnitState.h"
#include "GameEvent.h"
#include "Log.h"

// colors for all the units of a player
const Vector3D player_colors[] = {
    Vector3D ( 0.7f, 0.7f, 0.5 ),     // attackers color
    Vector3D ( 0.5f, 0.7f, 0.7 )      // seeker color
};

// messages in the view overlay
const Vector3D overlay_color = Vector3D ( 1, 0, 0 );
const Vector3D overlay[] = {
    Vector3D ( 5, 35, 0 ),
    Vector3D ( 5, 20, 0 ),
    Vector3D ( 5, 05, 0 )
};

const Vector3D obst_color (0.8f, 0.6f, 0.4f);

char *gamefile;


void view_update(void)
{
    Game& game = Game :: getInstance();

    // draw players teams
    Pool < Player > players = game.get_players();
    foreach ( pl, players )
    {
        Pool < Unit > units = (*pl).get_units();
        int id = (*pl).get_id();
        foreach ( u, units )
        {
            GameView::drawVehicle ((*u), player_colors [ id ]);
        }
    }

    // draw obstacles
    ObjectList *objects = game.get_objs();
    for ( ObjectList::iterator obj = objects->begin() ; obj != objects->end() ; ++obj )
    {
        // TODO this a dependency of OpenSteer library
        GameObject *gobj = dynamic_cast < GameObject* > ( *obj );
        GameView::drawObject ((*gobj), obst_color);
    }

    int sc = Lua::get_integer ("seeker_count");
    int fc = Lua::get_integer ("flag_count");

    std::ostringstream sc_str;
    std::ostringstream fc_str;
    std::ostringstream tm_str;

    sc_str << "Seeker captured: " << sc;
    fc_str << "Flag captured:   " << fc;
    tm_str << "Elapsed time:    " << game.current_time;

    OpenSteer :: draw2dTextAt2dLocation (sc_str, overlay[0], overlay_color);
    OpenSteer :: draw2dTextAt2dLocation (fc_str, overlay[1], overlay_color);
    OpenSteer :: draw2dTextAt2dLocation (tm_str, overlay[2], overlay_color);
}


class EventHandle : public UnitState
{
    UnitState* react_to_event ( const string &event_name, GameEventData *data ) {
        int sc = Lua::get_integer ("seeker_count");
        int fc = Lua::get_integer ("flag_count");

        Game::getInstance().reset();
        Game::getInstance().init(gamefile);

        // adding handler to the game events
        GameEvent *flag_event = Game::getInstance().get_event ( "flag_captured" );
        GameEvent *seeker_event = Game::getInstance().get_event ( "seeker_captured" );

        flag_event->add_listener ( this );
        seeker_event->add_listener ( this );

        Lua::set_integer ("seeker_count", sc);
        Lua::set_integer ("flag_count", fc);

        return NULL;
    }
};



int main(int argc, char **argv) {
    // setting debug output messages
    Logger :: set_level ( Logger :: DEBUG );

    LOG << "RTSAI testing application" << std::endl;
    if (argc > 1) {
        gamefile = argv[1];
        Game::getInstance().init(gamefile);

        // adding handler to the game events
        EventHandle handler;
        GameEvent *flag_event = Game::getInstance().get_event ( "flag_captured" );
        GameEvent *seeker_event = Game::getInstance().get_event ( "seeker_captured" );

        flag_event->add_listener ( &handler );
        seeker_event->add_listener ( &handler );

        // starting the game
        GameView :: init ( argc, argv, view_update );
        GameView :: start_loop();
    }
    else {
        LOG << "Usage: rtsai <game_description_file.lua>" << std::endl;
        exit(1);
    }
}
